package com.managers 
{
	import flash.display.Loader;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.IOErrorEvent;
	import flash.events.SecurityErrorEvent;
	import flash.net.URLLoader;
	import flash.net.URLRequest;
	import flash.utils.ByteArray;
	import flash.utils.Dictionary;
	/**
	 * @project FindTheEarl
	 * @file XmlManager.as
	 * @author Matthew Ladouceur
	 * @created Aug 12, 2011
	 *
	 * Copyright (c) 2011 marblemedia Interactive Inc.
	 * All Rights Reserved.
	 *
	 * http://www.marblemedia.com
	 */
	public class XmlManager 
	{
		private var _xmlLists:Dictionary = new Dictionary();
		private var _dispatcher:EventDispatcher;	
		private var _loader:URLLoader;
		
		public function getXML(listName:String):XMLList { return _xmlLists[listName]; }
		
		public function XmlManager() 
		{
			
		}
		
		/**
		 * Loads an xml file which can later be referenced by the list name given
		 * @param	file - the file to be loaded
		 * @param	listName - the name to reference the file by
		 */
		public function loadFile (file:String, listName:String ):void
		{
			trace( ME + ".loadFile("+file+")" );
			
			_loader = new URLLoader();
			_loader.addEventListener( Event.COMPLETE, function(e:Event):void{ onLoadFileComplete(e, listName), false, 0, true } );
			_loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler, false, 0, true);
			_loader.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler, false, 0, true);
			
			try {
				_loader.load( new URLRequest( file ));
			} catch ( error:Error ) {
				trace( "Unable to load requested document." );
				dispatchEvent(IOErrorEvent.IO_ERROR);
			}
		} // loadFile
		
		private function onLoadFileComplete(e:Event, listName:String):void {
			_loader.removeEventListener( Event.COMPLETE, onLoadFileComplete );
			var xml:XML = new XML( e.target.data );
			xml.ignoreWhitespace = true;
			
			_xmlLists[listName] = xml.data;
			
			// When SiteData is done loading and parsing data, it 
			trace(ME + "dispatching", listName+"_LOADED", "event");
			dispatchEvent(new Event(listName+"_LOADED"));
		}
		
		private function securityErrorHandler (event :SecurityErrorEvent):void
		{	
			dispatchEvent(event);
		}
		
		private function ioErrorHandler (event :IOErrorEvent):void
		{
			dispatchEvent(event);
		}
		
		// this class does NOT extend EventDispatcher, but instead follows Grant Skinner's approach
		// to Building a Static EventDispatcher found at http://gskinner.com/blog/archives/2007/07/building_a_stat.html
		public function addEventListener(...p_args:Array):void {
			if (_dispatcher == null) { _dispatcher = new EventDispatcher(); }
			_dispatcher.addEventListener.apply(null, p_args);
		}
		public function removeEventListener(...p_args:Array):void {
			if (_dispatcher == null) { return; }
			_dispatcher.removeEventListener.apply(null, p_args);
		}
		public function dispatchEvent(...p_args:Array):void {
			if (_dispatcher == null) { return; }
			_dispatcher.dispatchEvent.apply(null, p_args);
		}
		
		private const ME:String = "XmlManager ::";
		private static var _instance:XmlManager;
		
		public static function get instance():XmlManager {
			if (_instance == null) {
				_instance = new XmlManager();
			}
			return _instance;
		}
	}

}